/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package Search;

import com.sun.java.swing.plaf.windows.WindowsTreeUI;
import index.Element;
import index.StatsWordElement;
import index.StopList;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import sql.SQLInterface;
import stemmer.Stemmer;

/**
 *
 * @author Nuf
 */
public class Search {

    private static ArrayList<Query> queriesArray;
    private SearchResultsRelevance relevance;
    private ArrayList<Element> resultElements;
    private SearchResultsRelevance searchRelevance;
    private Stemmer stemmer;
    private String originalQuery;
    private String filteredQuery;
    private ArrayList<StatsWordElement> wordsResult;
    private ArrayList<ElementRelevance> paragraphesRelevance;
    private ArrayList<ElementRelevance> otherElementsRelevance;

    public Search(String query) {
        this.originalQuery = query;
        filteredQuery = "";
        stemmer = new Stemmer();
        wordsResult = new ArrayList<StatsWordElement>();
        paragraphesRelevance = new ArrayList<ElementRelevance>();
        otherElementsRelevance = new ArrayList<ElementRelevance>();
    }

    public void run() throws SQLException {
        SQLInterface.init();
        storeResults();
        analyseResults();

    }

    // Request DB to find relevants elemtns according to word's tf/idf and update resultElements
    public void storeResults() throws SQLException {
        boolean foundRelevance;
        // Parse the query
        parseQuery();
        System.out.println("Original query : \"" + originalQuery + "\"");
        System.out.println("Filetered query : \"" + filteredQuery + "\"");
        // We get all query's words
        String filteredWords[] = filteredQuery.split(" ");
        // For each word...
        for (String currentWord : filteredWords) {
            // We make the query
            ResultSet result = SQLInterface.wordQuery(currentWord);
            String word, document, element, type;
            int counter;
            float tf, idf;
            // We get each line
            while (result.next()) {
                // We store every column
                word = result.getString("word");
                document = result.getString("document");
                element = result.getString("elementXpath");
                counter = result.getInt("counter");
                tf = result.getFloat("tf");
                idf = result.getFloat("idf");
                type = result.getString("type");
                foundRelevance = false;
                // If it's a paragraph
                if (type.compareToIgnoreCase("P") == 0) {
                    // We seek if the ElementRelevance corresponding to the current paragraph exists
                    for (ElementRelevance e : paragraphesRelevance) {
                        if (e.getDocument().compareTo(document) == 0) {
                            if (e.getElement().compareTo(element) == 0) {
                                // If it does we update its relevance statistics
                                e.addOneWordStats(tf, idf);
                                foundRelevance = true;
                            }
                        }

                    }
                    // Else we add a new one to the list
                    if (!foundRelevance) {
                        ElementRelevance toAdd = new ElementRelevance(document, element, type);
                        toAdd.addOneWordStats(tf, idf);
                        paragraphesRelevance.add(toAdd);
                    }
                } // else if it's another element
                else {
                    // We seek if the ElementRelevance corresponding to the current paragraph exists
                    for (ElementRelevance e : otherElementsRelevance) {
                        if (e.getDocument().compareTo(document) == 0) {
                            if (e.getElement().compareTo(element) == 0) {
                                // If it does we update its relevance statistics
                                e.addOneWordStats(tf, idf);
                                foundRelevance = true;
                            }
                        }

                    }
                    // Else we add a new one to the list
                    if (!foundRelevance) {
                        ElementRelevance toAdd = new ElementRelevance(document, element, type);
                        toAdd.addOneWordStats(tf, idf);
                        otherElementsRelevance.add(toAdd);
                    }
                }


                /* We add the word statistics to the list
                 *(we might not need this list in the end,
                 * we keep it for now as we might find a use for it) */
                wordsResult.add(new StatsWordElement(element, document, word, counter, tf, idf));
            }
        }


//                System.out.println(result.getString("word") + " in " + result.getString("document") + " " + result.getString("elementXpath"));
    }

    public void analyseResults() {
        /*
         * We go through all non paragraph elements,
         * we add their tf/idf to the paragraph
         * in the same document multiplied by some coefficients
         */
        for (ElementRelevance otherElement : otherElementsRelevance) {
            for (ElementRelevance aParagraph : paragraphesRelevance) {
                if (otherElement.getDocument().compareTo(aParagraph.getDocument()) == 0) {
                    if (otherElement.getType().compareToIgnoreCase("TITRE") == 0) {
                        aParagraph.addOneWordStats(otherElement.getIdf() * ElementTypesCoeff.TITRE_COEFF, otherElement.getTf() * ElementTypesCoeff.TITRE_COEFF);
                    } else {
                        aParagraph.addOneWordStats(otherElement.getIdf(), otherElement.getTf());
                    }
                }
            }
        }
        Collections.sort(paragraphesRelevance);
    }

    public void parseQuery() {
        String[] queryWords = originalQuery.split(" ");
        for (int i = 0; i < queryWords.length; i++) {

            // Remove word if it is in the stoplist
            StopList sl = new StopList("..\\stopliste.txt");
            String stopWord;
            boolean toKeep = true;
            Iterator<String> it = sl.getStopListArray().iterator();
            while (it.hasNext()) {
                stopWord = it.next();
                if (queryWords[i].equalsIgnoreCase(stopWord)) {
                    toKeep = false;
                }
            }
            if (!toKeep) {
                queryWords[i] = null;
            }

            // Stemmer the word !
            if (queryWords[i] != null) {
                filteredQuery += stemmer.stemWord(queryWords[i]) + " ";
            }
        }
    }

    public ArrayList<ElementRelevance> getParagraphesRelevance() {
        return paragraphesRelevance;
    }

    @Override
    public String toString() {
        String str = "";
        for (ElementRelevance e : paragraphesRelevance) {
            str += ((e.getIdf() * e.getTf()) + " - " + e.getDocument() + " " + e.getElement());
        }
        return str;
    }
}
